#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
# include <iostream>
# include <string>

#define DEFAULT_PORT	80
struct sockaddr_in local, client_addr;
HANDLE t, Accept1, a[10];
void Send(SOCKET *sockClient);
void Rec(SOCKET sockClient);
int addr_len;
SOCKET msg_sock[10] = { 0 };
int number = 1;
long file_len;
int ResponseRequest(SOCKET soc, char* buf, int buf_len);
void getFileName(char* buf, char* fileName);
void file_send_success(SOCKET soc, long file_len);
void file_send_fail(SOCKET soc);

void Rec(SOCKET sockClient)
{
	char szBUFF[1024];
	long int Receive;
	int result;
	//while (1)
	//{
	//WaitForSingleObject(hMutex, INFINITE);
	memset(szBUFF, 0, sizeof(szBUFF));
	Receive = recv(sockClient, szBUFF, sizeof(szBUFF), 0);
	if (Receive <= 0)
	{
		printf("sdsd");
	}
	else{
		szBUFF[Receive] = '\0';
	}
	//SEND = send(msg_sock[b], szBUFF, sizeof(szBUFF), 0);
	puts(szBUFF);
	result = ResponseRequest(sockClient, szBUFF, Receive);
	file_send_success(sockClient, file_len);
	Sleep(1000);
	//}
	closesocket(sockClient);
}

void file_send_fail(SOCKET soc)
{
	long int send_len;
	char message[100];
	memset(message, 0, sizeof(message));
	sprintf(message, "file not found: 404");
	send_len = send(soc, message, sizeof(message), 0);
	closesocket(soc);
}
void file_send_success(SOCKET soc, long file_len)
{
	long int send_len;
	char httpmessage[100];
	char content_type[100];
	char content_length[100];
	memset(httpmessage, 0, sizeof(httpmessage));
	memset(content_type, 0, sizeof(content_type));
	memset(content_length, 0, sizeof(content_length));

	sprintf(httpmessage, "HTTP/1.0  200  OK ");
	send_len = send(soc, httpmessage, sizeof(httpmessage), 0);
	printf("%s\n", httpmessage);

	sprintf(content_type, "Content-type: TEXT/HTML");
	send_len = send(soc, content_type, sizeof(content_length), 0);
	printf("%s\n", content_type);

	sprintf(content_length, "Content-length: %ld", file_len);
	send_len = send(soc, content_length, sizeof(content_length), 0);
	printf("%s\n", content_length);
}

int ResponseRequest(SOCKET soc, char* buff, int buff_len)
{
	long read_len, send_len;
	char fileName[256] = "index.html";
	char readBuff[1024];
	FILE* targetFile;

	getFileName(buff, fileName);
	//get the file name, file type


	targetFile = fopen(fileName, "rb");
	if (targetFile == NULL)
	{
		printf("File does not exist");
		file_send_fail(soc);
		return 0;
	}
	fseek(targetFile, 0, SEEK_SET);
	fseek(targetFile, 0, SEEK_END); //move to the end of the char of the file
	file_len = ftell(targetFile); //calculate the length from begin to end
	fseek(targetFile, 0, SEEK_SET); //move back to begin point
	do
	{
		memset(readBuff, 0, sizeof(readBuff));
		read_len = fread(readBuff, sizeof(char), 1024, targetFile);
		//printf("readbuff : %s", readBuff);
		if (read_len > 0)
		{
			send_len = send(soc, readBuff, read_len, 0);
			//file_len = file_len - send_len;
		}
	} while (!feof(targetFile));
	fclose(targetFile);
	return 1;
}

void getFileName(char* buff, char* fileName)
{
	int length = 0;
	char *begin, *end;
	//char default[11] = "index.html";

	//URL starting point
	begin = strchr(buff, '/');
	begin++;

	//URL end point (From begin to end is the whole URL address)
	end = strchr(begin, ' ');
	*end = '\0';
	length = end - begin;
	if (length > 0)
	{
		memset(fileName, 0, sizeof(fileName));
		memcpy(fileName, begin, length);
		fileName[length] = '\0';
		puts(fileName);
	}
}

void Acc(SOCKET sock)
{
	addr_len = sizeof(client_addr);
	//int SEND;
	while (addr_len > 0 && number < 1000)
	{
		//printf("\n%%%%%%%%%%%%%%%\n");
		msg_sock[number] = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		//printf("connect successfully:%d\n", number);
		//SEND = send(msg_sock[number], _itoa(number, str, 10), 25, 0);
		a[number] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Rec, (LPVOID)msg_sock[number], 0, 0);
		//t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Send, (LPVOID)&msg_sock, 0, 0);
		number++;
	}
	WaitForSingleObject(a[number], INFINITE);
	//	WaitForSingleObject(t, INFINITE);
	CloseHandle(a[number]);
	//CloseHandle(t);
}

void Send(SOCKET *sockClient)
{
	char message[1000];
	int SEND;
	while (1)
	{
		//WaitForSingleObject(hMutex, INFINITE);
		gets_s(message, 100);
		for (int i = 1; i <= sizeof(sockClient); i++)
		{
			SEND = send(sockClient[i], message, sizeof(message), 0);
			if (SEND <= 0)
			{
				break;
			}
			else if (SEND > 0 && strcmp(message, "Bye") == 0)
			{
				break;
			}
			Sleep(1000);
		}
	}
	closesocket(*sockClient);
	//WSACleanup();
}



int main(int argc, char **argv)
{

	while (1){
		SOCKET sock;
		WSADATA wsaData;

		if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR) {
			// stderr: standard error are printed to the screen.
			fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
			//WSACleanup function terminates use of the Windows Sockets DLL. 
			WSACleanup();
			return -1;
		}
		// Fill in the address structure
		local.sin_family = AF_INET;
		local.sin_addr.s_addr = INADDR_ANY;
		local.sin_port = htons(DEFAULT_PORT);
		//sock[0] = socket(AF_INET, SOCK_STREAM, 0);	//TCp socket


		/*local.sin_family = AF_INET;
		local.sin_addr.s_addr = INADDR_ANY;
		local.sin_port = htons(DEFAULT_PORT);*/
		sock = socket(AF_INET, SOCK_STREAM, 0);	//TCp socket


		if (sock == INVALID_SOCKET) {
			fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
			WSACleanup();
			return -1;
		}

		if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) {
			fprintf(stderr, "bind() failed with error %d\n", WSAGetLastError());
			WSACleanup();
			return -1;
		}

		printf("Listening\n");
		if (listen(sock, 100) == SOCKET_ERROR) {
			fprintf(stderr, "listen() failed with error %d\n", WSAGetLastError());
			WSACleanup();
		}
		if (listen(sock, 100) != SOCKET_ERROR)
		{
			Accept1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Acc, (LPVOID)sock, 0, 0);
			WaitForSingleObject(Accept1, INFINITE);
		}
		//waiting for the connections
		//printf("Waiting for the connections ........\n");
		///while (1)
		//{
		//addr_len = sizeof(client_addr);
		//msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		//addr_len = sizeof(client_addr);
		//msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
		//printf("accepted connection from %s, port %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));
		CloseHandle(Accept1);
	}
	//closesocket(msg_sock);
	WSACleanup();
}
